home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / cawf404.zip / pass3.c < prev    next >
C/C++ Source or Header  |  1993-12-07  |  15KB  |  650 lines

  1. /*
  2.  *    pass3.c - cawf(1) pass 3 function
  3.  */
  4.  
  5. /*
  6.  *    Copyright (c) 1991 Purdue University Research Foundation,
  7.  *    West Lafayette, Indiana 47907.  All rights reserved.
  8.  *
  9.  *    Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
  10.  *    University Computing Center.  Not derived from licensed software;
  11.  *    derived from awf(1) by Henry Spencer of the University of Toronto.
  12.  *
  13.  *    Permission is granted to anyone to use this software for any
  14.  *    purpose on any computer system, and to alter it and redistribute
  15.  *    it freely, subject to the following restrictions:
  16.  *
  17.  *    1. The author is not responsible for any consequences of use of
  18.  *       this software, even if they arise from flaws in it.
  19.  *
  20.  *    2. The origin of this software must not be misrepresented, either
  21.  *       by explicit claim or by omission.  Credits must appear in the
  22.  *       documentation.
  23.  *
  24.  *    3. Altered versions must be plainly marked as such, and must not
  25.  *       be misrepresented as being the original software.  Credits must
  26.  *       appear in the documentation.
  27.  *
  28.  *    4. This notice may not be removed or altered.
  29.  */
  30.  
  31. #include "cawf.h"
  32.  
  33. void
  34. Pass3(len, word, wl, sarg, narg)
  35.     int len;            /* output length -- negative is
  36.                      * special */
  37.     unsigned char *word;        /* word */
  38.     int wl;                /* real word length */
  39.     unsigned char *sarg;        /* string argument */
  40.     int narg;            /* numeric argument */
  41. {
  42.     int addto;            /* spaces to add to all words */
  43.     static int fp = 1;        /* first page print status */
  44.     int i, j, k;            /* temporary index */
  45.     unsigned char msg[MAXLINE];    /* message buffer */
  46.     int n;                /* temporary number */
  47.     unsigned char *s1;        /* temporary string pointer */
  48.     int sp = 0;            /* no-break spacing switch */
  49.     int sp_Outll;            /* sp-saved Outll */
  50.     char sp_Outln;            /* sp-saved Outln[0] */
  51.     int sp_Outlx;            /* sp-saved Outlx */
  52.     int sp_Padx;            /* sp-saved Padx */
  53.     int sp_Tind;            /* sp-saved Tind */
  54.     int xsp;            /* extra spaces to add */
  55.     int vsp;            /* vertical spacing status */
  56.  
  57.     vsp = 0;
  58.     /*
  59.      * If not a special command, process a word.
  60.      */
  61.     if (len >= 0 && Outll < 0) {
  62.     /*
  63.      * Enter first word.
  64.      */
  65.         (void) memcpy((void *)Outln, (void *)word, (size_t)wl);
  66.         Outlx = wl;
  67.         Outll = len;
  68.         Padx = 0;
  69.     } else if (len >= 0
  70.            && (Outll+Contlen+len+narg) <= (LL-Pgoff-Ind-Tind)) {
  71.     /*
  72.      * The word fits, so enter it.
  73.      */
  74.         if ((Contlen + len) > 0) {
  75. line_too_big:
  76.             if ((Outlx + Contlen + wl) >= MAXOLL) {
  77.                 Error3(len, (char *)word, (char *)sarg, narg,
  78.                     "output line too big");
  79.                 return;
  80.             } else {
  81.                 if (Contlen > 0 && Cont != NULL) {
  82.                     if (Contlen == 1 && *Cont == ' ') {
  83.                         Padchar[Padx++] = Outlx;
  84.                         Outln[Outlx++] = ' ';
  85.                     } else {
  86.                         (void) strcpy((char *)&Outln[Outlx],
  87.                         (char *)Cont);
  88.                         Outlx += Contlen;
  89.                     }
  90.                 }
  91.                 if (len > 0) {
  92.                     (void) memcpy((void *)&Outln[Outlx],
  93.                     (void *)word, (size_t)wl);
  94.                     Outlx += wl;
  95.                 }
  96.             }
  97.         }
  98.         Outll += Contlen + len;
  99.     } else if (len == NOBREAK || len == MESSAGE) {
  100.         /*
  101.          * Do nothing (equivalent to break)
  102.          */
  103.     } else if (len == DOBREAK && strcmp((char *)word, "need") == 0
  104.            &&  (Nxtln + narg) < (Pglen + 1 - Botmarg)) {
  105.         /*
  106.          * Do nothing, because there is room on the page.
  107.          */
  108.     } else if (len == DOBREAK && strcmp((char *)word, "toindent") == 0
  109.            &&  (Ind + Tind + Outll) < Ind) {
  110.     /*
  111.      * Move to indent position with line - there is room.
  112.      */
  113.         n = Ind - (Ind + Tind + Outll);
  114.         Outll += n;
  115.         if ((Outlx + n) >= MAXOLL)
  116.             goto line_too_big;
  117.         for (i = n; i; i--)
  118.             Outln[Outlx++] = ' ';
  119.         Padx = 0;
  120.         Free(&Cont);
  121.         Contlen = 0;
  122.     } else if (Outll >= 0
  123.            || (len == DOBREAK && strcmp((char *)word, "need") == 0)
  124.            || (len == RAWLINE)) {
  125.     /*
  126.      * A non-empty line or a "need" or a RAWLINE forces output.
  127.      */
  128.         vsp = 0;
  129.  
  130. print_line:
  131.         if (Nxtln == 1) {
  132.         /*
  133.          * We're at the top of the page.
  134.          *
  135.          * Determine if the page is in the printing range.
  136.          *
  137.          * Issue the header.
  138.          */
  139.             j = fp;
  140.             if (Pageprt = PageInRange(Thispg)) {
  141.                 if (!fp)
  142.                     Charput("\f");
  143.                 fp = 0;
  144.             }
  145.             for (i = (Topmarg - 1)/2; i > 0; i--) {
  146.                 Charput("\n");
  147.                 Nxtln++;
  148.             }
  149.             /*
  150.              * Print the page header, as required.
  151.              */
  152.             if (Fph || !j) {
  153.                 i = LenprtHF(Hdc, Thispg, 0, NULL)
  154.                   + LenprtHF(Hdl, Thispg, 0, NULL)
  155.                   + LenprtHF(Hdr, Thispg, 0, NULL) + 2;
  156.                 j = (LL - i - Pgoff) / 2 + 1;
  157.                 n = LL - Pgoff - i - j + 2;
  158.                 for (k = 0; k < Pgoff; k++)
  159.                     Charput(" ");
  160.                 if (Hdl)
  161.                     (void) LenprtHF(Hdl, Thispg, 1, NULL);
  162.                 while (j--)
  163.                     Charput(" ");
  164.                 if (Hdc)
  165.                     (void) LenprtHF(Hdc, Thispg, 1, NULL);
  166.                 while (n--)
  167.                     Charput(" ");
  168.                 if (Hdr)
  169.                     (void) LenprtHF(Hdr, Thispg, 1, NULL);
  170.                 Charput("\n");
  171.             } else
  172.                 Charput("\n");
  173.             Nxtln++;
  174.             while(Nxtln <= Topmarg) {
  175.                 Charput("\n");
  176.                 Nxtln++;
  177.             }
  178.         }
  179.         /*
  180.          * If this is a raw line, simply output the string argument.
  181.          */
  182.         if (len == RAWLINE) {
  183.             Stringput(sarg, strlen((char *)sarg));
  184.             Charput("\n");
  185.             Nxtln++;
  186.         } else {
  187.  
  188.         /*
  189.          * Print a normal output line.
  190.          */
  191.         /*
  192.          *  Add a trailing hyphen, if mecessary.
  193.          */
  194.             if (vsp == 0 && Eollen > 0 && Eol != NULL) {
  195.             i = strlen((char *)Eol);
  196.             if ((Outlx + i) >= MAXOLL)
  197.                 goto line_too_big;
  198.             (void) memcpy((void *)&Outln[Outlx], (void *)Eol, i);
  199.             Outlx += i;
  200.             Outll += Eollen;
  201.             }
  202.         /*
  203.          * Trim trailing spaces from the output line.
  204.          */
  205.                  while (Outlx > 0) {
  206.             if (Outln[Outlx - 1] != ' ')
  207.                 break;
  208.             if (Padx > 0 && (Outlx - 1) == Padchar[Padx - 1])
  209.                 Padx--;
  210.             Outlx--;
  211.             Outll--;
  212.             }
  213.             if (Outlx == 0) {
  214.             Charput("\n");
  215.             } else if (len == DOBREAK
  216.              && strcmp((char *)word, "center") == 0) {
  217.             /*
  218.              * Center the output line.
  219.              */
  220.             i = (LL - Pgoff - Outll) / 2;
  221.             if (i < 0)
  222.                 i = 0;
  223.             for (j = (Pgoff + Ind + Tind + i); j; j--)
  224.                 Charput(" ");
  225.             Stringput(Outln, Outlx);
  226.             Charput("\n");
  227.             } else if (Adj == LEFTADJ
  228.                    || (Adj == BOTHADJ && (len < 0 || Padx == 0))) {
  229.             /*
  230.              * No right margin adjustment - disabled, inappropriate
  231.              * (line ended by break) or impossible.
  232.              */
  233.             for (i = 0; i < (Pgoff + Ind + Tind); i++)
  234.                 Charput(" ");
  235.             Stringput(Outln, Outlx);
  236.             Charput("\n");
  237.             } else if (Adj == BOTHADJ) {
  238.             /*
  239.              * Adjust right margin.
  240.              */
  241.             for (i = 0; i < (Pgoff + Ind + Tind); i++)
  242.                 Charput(" ");
  243.             i = LL - (Pgoff + Ind + Tind);
  244.             j = i - Outll;
  245.             addto = Padx ? (j / Padx) : 0;
  246.             xsp = j - (Padx * addto);
  247.             for (i = k = 0; i < Padx; i++) {
  248.                 while (k < Outlx && k <= Padchar[i]) {
  249.                 Charput(&Outln[k]);
  250.                 k++;
  251.                 }
  252.                 if (k >= Outlx)
  253.                 break;
  254.                 j = addto;
  255.                 if (Padfrom == PADLEFT) {
  256.                 if (i < xsp)
  257.                     j++;
  258.                 } else if (i >= (Padx - xsp))
  259.                 j++;
  260.                 while (j--)
  261.                 Charput(" ");
  262.             }
  263.             if ((Outlx - k) > 0)
  264.                 Stringput(&Outln[k], Outlx - k);
  265.             Charput("\n");
  266.             Padfrom = (Padfrom == PADLEFT) ? PADRIGHT : PADLEFT;
  267.             }
  268.         /*
  269.          * End of line housekeeping
  270.          */
  271.             Nxtln++;
  272.             Outll = -1;
  273.             Outlx = 0;
  274.             Padx = 0;
  275.             Tind = 0;
  276.             Nospmode = 0;
  277.             if (vsp == 0 && len == DOBREAK
  278.             &&  strcmp((char *)word, "need") == 0) {
  279.             /*
  280.              * Break caused by "need" - satisfy it.
  281.              */
  282.             while (Nxtln < (Pglen + 1 - Botmarg)) {
  283.                 Charput("\n");
  284.                 Nxtln++;
  285.             }
  286.             }
  287.         }
  288.         if (Nxtln >= (Pglen + 1 - Botmarg)) {
  289.         /*
  290.          * Footer required
  291.          */
  292.             for (i = (Botmarg - 1)/2; i > 0; i--) {
  293.                 Charput("\n");
  294.                 Nxtln++;
  295.             }
  296.             i = LenprtHF(Ftl, Thispg, 0, NULL)
  297.               + LenprtHF(Ftc, Thispg, 0, NULL)
  298.               + LenprtHF(Ftr, Thispg, 0, NULL) + 2;
  299.             j = (LL - i - Pgoff) / 2 + 1;
  300.             n = LL - Pgoff - i - j + 2;
  301.             for (k = 0; k < Pgoff; k++)
  302.                 Charput(" ");
  303.             if (Ftl)
  304.                 (void)LenprtHF(Ftl, Thispg, 1, NULL);
  305.             while (j--)
  306.                 Charput(" ");
  307.             if (Ftc)
  308.                 (void)L